<!DOCTYPE html>
<html lang="en">
<head>
    <title>囧么肥事</title>
    <meta charset="UTF-8"/>
    <meta name="viewport"
          content="width=device-width,height=device-height,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta http-equiv="Content-Type" content="text/html;"/>
    <meta name="renderer" content="webkit">
    <!--解决页面加载网络图片的403问题 , 可以让img标签预加载网络图片-->
    <meta name="referrer" content="no-referrer" />

    <!--markdown S -->
    <link rel="stylesheet" type="text/css" href="../../static/css/export_setting_css.css"/>
    <link rel="stylesheet" type="text/css" href="../../static/css/markdown_preview_css.css"/>
    <!--markdown E -->

    <!--left bar tools css E-->
    <link rel="stylesheet" type="text/css" href="../../static/css/nav.css">
    <link rel="stylesheet" type="text/css" href="http://www.jq22.com/jquery/font-awesome.4.6.0.css">
    <!--left bar tools css E-->

    <!-- 滚动条 S -->
    <link rel="stylesheet" href="../../static/css/optiscroll.css">
    <!-- 滚动条 E -->
</head>
<body>
<div id="m-wrapper" class="m-wrapper optiscroll">
    <!-- top 锚点 -->
    <a id="top"></a>

    <!-- left bar tools S -->
    <div class="leftNav-item">
        <ul>
            <li>
                <i class="fa fa-location-arrow"></i>
                <a href="http://jiongmefeishi.gitee.io/monster-blog/" target="_blank" class="rota">个人网站</a>
            </li>

            <li title="Git">
                <i class="fa fa-code-fork" aria-hidden="true"></i>
                <a href="http://jiongmefeishi.gitee.io/monster-blog/" target="_blank" class="rota">Git Page</a>
            </li>

            <li lay-data="img" data-fooc="http://resource.zqtaotao.cn/wx/qrcode/jiongmefeishi.jpg">
                <i class="fa fa-comments-o"></i><a href="javascript:;" class="rota">公众号</a>
            </li>

            <li lay-data="img" data-fooc="http://resource.zqtaotao.cn/weixincode.png">
                <i class="fa fa-money"></i><a href="javascript:;" class="rota">小额打赏</a>
            </li>
            <li title="返回顶部" class="for-top">
                <i class="fa fa-arrow-up"></i>
                <a href="#top" class="rota">去顶部</a>
            </li>
        </ul>
    </div>
    <!-- left bar tools E -->

    <!--content S-->
    <div id="export_content"><div class="output_wrapper" id="output_wrapper_id"><h3 id="hk8sstatefulsetspod"><span>k8s集群StatefulSets的Pod调度查询丢失问题?</span></h3>
        <pre><code class="hljs">考点之简单介绍下StatefulSets&nbsp;和&nbsp;Deployment&nbsp;之间有什么本质区别？特定场景该如何做出选择呢？<br></code></pre>
        <pre><code class="hljs">考点之你能辩证的说说看StatefulSets&nbsp;和&nbsp;Deployment具体有哪些区别嘛？<br></code></pre>
        <pre><code class="hljs">考点之你了解k8s集群StatefulSets的Pod调度查询丢失问题吗？k8s集群中StatefulSet管理的Pod已经完成调度并启动，为什么还是无法查询Pod&nbsp;的&nbsp;DNS&nbsp;命名？<br></code></pre>
        <figure><img src="https://img-blog.csdnimg.cn/img_convert/88b0197aca9d2317471a96e6573b1882.gif" alt="" title=""><figcaption></figcaption></figure>
        <h3 id="h"><span>囧么肥事-胡说八道</span></h3>
        <figure><img src="https://img-blog.csdnimg.cn/img_convert/64bb6ae882304e8d317de2104bd04634.png" alt="" title=""><figcaption></figcaption></figure>
        <figure><img src="https://img-blog.csdnimg.cn/img_convert/0bed3d46352edf5dee08633ef1982781.png" alt="" title=""><figcaption></figcaption></figure>
        <h3 id="hstatefulsetsdeployment"><span>简单介绍下StatefulSets 和 Deployment 之间有什么本质区别？</span></h3>
        <p>首先、<code>StatefulSet</code> 和<code>Deployment</code> 都是用来管理应用的工作负载 API 对象，都管理基于各自相同容器规约的一组 Pod，同时负责各自管理的Pod 集合的部署和扩缩、更新回滚等。</p>
        <p>但和 <code>Deployment</code> <strong>本质上不同</strong>的是，<code>StatefulSets</code> 用来管理<strong>有状态应用</strong>，而<code>Deployment</code> 负责管理<strong>无状态应用</strong>。</p>
        <p>如果应用程序<strong>不需要任何稳定的</strong>标识符或有序的部署、删除或伸缩，则应该使用 由一组<strong>无状态的副本控制器</strong>提供的工作负载来部署应用程序，比如 <code>Deployment</code>或者<code>ReplicaSet</code>。</p>
        <p>如果希望使用<strong>存储卷为工作负载提供持久存储</strong>，可以使用 <code>StatefulSet</code> 作为解决方案的一部分。 </p>
        <p>尽管 StatefulSet 中的单个 Pod 仍可能出现故障， 但<strong>持久的 Pod 标识符</strong> 可以更容易将<strong>现有卷</strong>与于重新调度的Pod进行绑定。</p>
        <p>说道这里，下面简单介绍一下，应用分类：</p>
        <p><strong>应用通常可以分为两大类：有状态与无状态</strong></p>
        <p><strong>无状态应用</strong></p>
        <pre><code class="hljs vbscript">简单理解就是没有特殊状态的服务<br><br>服务和数据分离，本身不存储数据<br><br>各个请求对于服务器来说统一无差别处理<br><br>请求可以随机发送到任意一台<span class="hljs-built_in">server</span>上<br><br>请求自身携带了所有服务端所需要的所有参数<br><br>服务自身不存储跟请求相关的任何数据<br></code></pre>
        <p><strong>有状态应用</strong></p>
        <pre><code class="hljs">容器数据需要持久化保持<br><br>对于有数据存储功能的服务<br><br>每个实例都需要有自己独立的持久化存储<br><br>或者指多线程类型的服务、队列<br><br>mysql数据库、kafka、zookeeper等<br></code></pre>
        <p>如果server是有状态的，客户端需要始终把请求发到同一台server才行，</p>
        <p>同时，这里理解StatefulSets 两个关键点：<strong>1、稳定的 2、有序的</strong></p>
        <pre><code class="hljs">“稳定的”意味着&nbsp;Pod&nbsp;调度或重调度的整个过程是有持久性的<br></code></pre>
        <pre><code class="hljs">“有序的”意味着&nbsp;Pod&nbsp;调度或重调度的整个过程是需要保持顺序的<br></code></pre>
        <p>关于Deployment 的具体情况，可参考：<a href="https://mp.weixin.qq.com/s?__biz=Mzg3NjU0NDE4NQ==&amp;mid=2247484214&amp;idx=1&amp;sn=7a0a593abbcd34347351bcc3ecd6785a&amp;chksm=cf31eae0f84663f61600e14108ebd7b0db326d26d1f78ca7686e685c4de4728af80b54de3b4c#rd">【跟k8s工作负载Deployments的缘起缘灭】</a></p>
        <h3 id="hstatefulsetsdeployment-1"><span>你能辩证的说说看StatefulSets 和 Deployment具体有哪些区别嘛？</span></h3>
        <p><strong>Deployment管理的Pod特点</strong></p>
        <p>Deployment被设计用来管理<strong>无状态服务</strong>的pod，每个pod完全一致</p>
        <ul>
            <li>无序性：无状态服务的多个Pod副本创建和销毁是<strong>无序</strong>的，可以并行创建或销毁，相互之间不必等待，除了需要遵守规约中定义的副本个数之外，没有其他制约。</li>
            <li>随机性：无状态服务的多个Pod副本的名称是<strong>随机</strong>的，pod被重新启动调度后，它的名称与IP都会发生变化，替换为一个新的副本。</li>
            <li>共享性：无状态服务的多个Pod副本<strong>共享存储卷</strong>。Deployment中Pod基于template定义存储卷，所有副本集共用一个存储卷。</li>
        </ul>
        <figure><img src="https://img-blog.csdnimg.cn/img_convert/ffb00caab57e9b89a4f497c6f5ed4de3.gif" alt="" title=""><figcaption></figcaption></figure>
        <p><strong>StatefulSets管理的Pod特点</strong></p>
        <p>StatefulSets 被设计用来管理<strong>有状态</strong>的应用，StatefulSet 管理的 Pod <strong>具有唯一的标识</strong>，该标识包括顺序标识、稳定的网络标识和稳定的存储。 并且该标识和 Pod 是绑定，<strong>不管它被调度在哪个节点上，最终都会被绑定这个唯一标识</strong>。</p>
        <ul>
            <li>唯一性：对于具有 N 个副本的 StatefulSet，它管理的每个 Pod 将被分配一个整数序号，<strong>该序号在 StatefulSet 上是唯一的</strong>。</li>
            <li>顺序性：<strong>顺序标识</strong>、Pod 调度过程，无论是启动、销毁、更新都需要严格遵守顺序。<strong>有序优雅的部署和缩放，有序自动的滚动更新</strong>。</li>
            <li><span>稳定的网络标识：Pod主机名、DNS地址不会随着Pod被重新调度而发生变化。</span></li>
            <li>稳定的持久化存储：Pod被重新调度后，不会删除原有的PV，重新调度成功后，<strong>继续挂载绑定原有的PV</strong>，从而保证了数据的完整性和一致性。</li>
        </ul>
        <h3 id="hk8sstatefulsetspod-1"><span>你了解过k8s集群StatefulSets的Pod调度查询丢失问题吗？</span></h3>
        <p>k8s集群中<code>StatefulSet</code>管理的Pod已经完成调度并启动，为什么还是无法查询Pod 的 DNS 命名？如果需要在 Pod 调度完成之后及时发现，该怎么做？</p>
        <p><strong>先看看StatefulSet是如何为每个Pod分配DNS的呢？</strong></p>
        <p><code>StatefulSet</code> 中管理的每个 Pod 会根据 <strong>StatefulSet 的名称</strong>和 以及为 Pod 的分配的<strong>有序索引（序号）</strong>，派生出它的主机名。 </p>
        <p>组合主机名的格式为：</p>
        <pre><code class="hljs javascript">$(StatefulSet&nbsp;名称)-$(序号)<br></code></pre>
        <p><code>StatefulSet</code> 使用 <code>Headless Services</code> 控制内部 Pod 的网络域。</p>
        <p>通过<code>Headless Service为Pod</code>编号，在DNS服务器中生成带有编号的DNS记录，从而可以达到通过Pod名字定位到相应的服务</p>
        <p>管理域的服务的格式为： </p>
        <pre><code class="hljs javascript">$(服务名称).$(命名空间).svc.cluster.local<br></code></pre>
        <p>其中 <code>cluster.local</code> 是集群域。 一旦每个 Pod 创建成功，就会得到一个匹配的 DNS 子域，格式为： <code>$(pod 名称).$(所属服务的 DNS 域名)</code>，其中所属服务由 <code>StatefulSet</code> 的 <code>serviceName</code> 域来设定。</p>
        <p><strong>了解完分配和组成，接下来说一下为什么会出现查询失败的情况呢？</strong></p>
        <p>第一种情况，Pod尚在创建过程中，这时候查询，DNS命名还未分配成功</p>
        <p>第二种情况，Pod已经创建成功，取决于集群域内部 DNS 的配置，可能无法查询一个刚刚启动的 Pod 的 DNS 命名。原因是k8s有个<strong>负缓存</strong>的概念。</p>
        <p><strong>负缓存 (在 DNS 中较为常见)</strong> </p>
        <pre><code class="hljs go">之前失败的查询结果会被记录和重用至少若干秒钟<br><br>默认缓存时长为&nbsp;<span class="hljs-number">30s</span><br><br>查询过程<br><br>第一次查询结果是失败<br>结果记录到负缓存中，标注失败<br><br>在缓存周期内查询，直接从负缓存中取，结果是失败<br></code></pre>
        <p><strong>如何及时发现创建的Pod的DNS命名？</strong></p>
        <p>如果需要在 Pod 被创建之后及时发现它们，有以下选项：</p>
        <ul>
            <li>直接查询 <code>Kubernetes API</code>（比如，利用 <code>watch</code> 机制）而不是依赖于 DNS 查询</li>
            <li>缩短 <code>Kubernetes DNS</code> 驱动的<strong>缓存时长</strong>（修改 <code>CoreDNS</code> 的 <code>ConfigMap</code>，目前DNS缓存时长为 30 秒）</li>
        </ul>
        <figure><img src="https://img-blog.csdnimg.cn/img_convert/420684d322028960ca7fb057873d14f8.gif" alt="" title=""><figcaption></figcaption></figure>
        <hr>
        <blockquote>
            <p>获取更多干货，欢迎关注微信公众号：囧么肥事</p>
        </blockquote>
        <p>Kubernetes 推荐学习书</p>
        <blockquote>
            <p>Kubernetes权威指南PDF<br>链接: https://pan.baidu.com/s/11huLHJkCeIPZqSyLEoUEmQ 提取码:sa88</p>
        </blockquote>
        <hr>
        <figure><img src="https://img-blog.csdnimg.cn/70b8bb984a494cc983d24c03ce1820bc.png" alt="" title=""><figcaption></figcaption></figure></div></div>
    <!--content E-->
</div>



</body>
<!--left bar tools js S-->
<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script type="text/javascript" src="../../static/js/nav.js"></script>
<!--left bar tools js E-->

<!-- 滚动条 S -->
<script type="text/javascript" src="../../static/js/optiscroll.js"></script>
<!-- 滚动条 E -->

<!--commonjs S-->
<script type="text/javascript" src="../../static/js/common.js"></script>
<!--commonjs E-->

</html>
